home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Src Code / TEEPROCS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  60.4 KB  |  2,149 lines

  1. {****************************************}
  2. {   TeeChart and TeeTree VCL Library     }
  3. { Copyright (c) 1995-98 by David Berneda }
  4. {        All Rights Reserved             }
  5. {****************************************}
  6. {$R-,S-,Q-,I-,A+,U-,X+,B-,W-,P-,V-}
  7. {$I teedefs.inc}
  8. {$IFNDEF D1}
  9. {$H+}
  10. {$ENDIF}
  11. unit TeeProcs;
  12.  
  13. interface
  14.  
  15. Uses Classes,Messages,
  16.      {$IFDEF D1}
  17.      WinProcs,WinTypes,Menus,
  18.      {$ELSE}
  19.      Windows,
  20.      {$ENDIF}
  21.      TeCanvas,Printers,Clipbrd,ExtCtrls,Graphics,Controls,Forms,SysUtils;
  22.  
  23. Const  MaxDefaultColors=16;
  24.        ColorPalette:Array[1..MaxDefaultColors] of TColor=
  25.         ( clRed,
  26.           clGreen,
  27.           clYellow,
  28.           clBlue,
  29.           clWhite,
  30.           clGray,
  31.           clFuchsia,
  32.           clTeal,
  33.           clNavy,
  34.           clMaroon,
  35.           clLime,
  36.           clOlive,
  37.           clPurple,
  38.           clSilver,
  39.           clAqua,
  40.           clBlack);
  41.  
  42.    TeeDefVerticalMargin = 4;
  43.    TeeDefHorizMargin    = 3;
  44.  
  45.    TeeMsg_ExportChartName     = 'Chart.';  { <-- dont translate }
  46.  
  47.    crTeeHand              = 2020;      { Hand cursor }
  48.    TeeMsg_TeeHand         = 'crTeeHand'; { string cursor name (dont translate) }
  49.  
  50.    TeeLineSeparator:{$IFNDEF D1}AnsiChar{$ELSE}Char{$ENDIF} = #13;
  51.  
  52.    TeeDefault_PrintMargin = 15;
  53.  
  54.    { Printing }
  55.    TeeNormalPrintDetail   =    0;
  56.    TeeHighPrintDetail     = -100;
  57.  
  58.    TeeDef3DPercent        = 15;
  59.  
  60. Var
  61.   TeeClipWhenPrinting   : Boolean;
  62.   TeeClipWhenMetafiling : Boolean;
  63.   TeeEraseBack          : Boolean;
  64.   { Should Panel background to be printed ? Default: False }
  65.   PrintTeePanel         : Boolean;
  66.  
  67. type
  68.   ChartException=class(Exception);
  69.  
  70.   TDateTimeStep=(  dtOneSecond,
  71.                    dtFiveSeconds,
  72.                    dtTenSeconds,
  73.                    dtFifteenSeconds,
  74.                    dtThirtySeconds,
  75.                    dtOneMinute,
  76.                    dtFiveMinutes,
  77.                    dtTenMinutes,
  78.                    dtFifteenMinutes,
  79.                    dtThirtyMinutes,
  80.                    dtOneHour,
  81.                    dtTwoHours,
  82.                    dtSixHours,
  83.                    dtTwelveHours,
  84.                    dtOneDay,
  85.                    dtTwoDays,
  86.                    dtThreeDays,
  87.                    dtOneWeek,
  88.                    dtHalfMonth,
  89.                    dtOneMonth,
  90.                    dtTwoMonths,
  91.                    dtThreeMonths,
  92.                    dtFourMonths,
  93.                    dtSixMonths,
  94.                    dtOneYear,
  95.                    dtNone );
  96.  
  97. Const
  98.     DateTimeStep:Array[TDateTimeStep] of Double=
  99.       ( 1.0/86400.0,  5.0/86400.0,  10.0/86400.0,
  100.         0.25/1440.0,  0.5/1440.0,    1.0/1440.0,
  101.         5.0/1440.0,  10.0/1440.0,    0.25/24.0,
  102.         0.5/24.0 ,    1.0/24.0 ,  2.0/24.0 ,  6.0/24.0 ,
  103.         12.0/24.0,    1, 2, 3, 7, 15, 30, 60, 90, 120, 182, 365, {none:} 1
  104.       );
  105.  
  106. type
  107.   TZoomPanningRecord=class
  108.   public
  109.     Active      : Boolean;
  110.     X0,Y0,X1,Y1 : Longint;
  111.     Procedure Check;
  112.     Procedure Activate(x,y:Longint);
  113.   end;
  114.  
  115.   TTeeBackImageMode=(pbmStretch,pbmTile,pbmCenter);
  116.  
  117.   TCustomTeePanel=class(TCustomPanel)
  118.   private
  119.     F3DPercent        : Integer;
  120.     FApplyZOrder      : Boolean;
  121.     FChartBounds      : TRect;
  122.     FChartWidth       : Integer;
  123.     FChartHeight      : Integer;
  124.     FChartXCenter     : Integer;
  125.     FChartYCenter     : Integer;
  126.     FDelphiCanvas     : TCanvas;
  127.     FHeight3D         : Integer;
  128.     FMargins          : TRect;
  129.     FOriginalCursor   : TCursor;
  130.     FPanning          : TZoomPanningRecord;
  131.     FPrinting         : Boolean;
  132.     FPrintProportional: Boolean;
  133.     FPrintResolution  : Integer;
  134.     FView3D           : Boolean;
  135.     FView3DOptions    : TView3DOptions;
  136.     FWidth3D          : Integer;
  137.     FZoom             : TZoomPanningRecord;
  138.     Function GetMargin(Index:Integer):Integer;
  139.     Function GetBufferedDisplay:Boolean;
  140.     Procedure SetBufferedDisplay(Value:Boolean);
  141.     procedure SetView3D(Value:Boolean);
  142.     procedure SetView3DOptions(Value:TView3DOptions);
  143.     Function GetMonochrome:Boolean;
  144.     Procedure SetMonochrome(Value:Boolean);
  145.     Procedure Set3DPercent(Value:Integer);
  146.   protected
  147.     InternalCanvas    : TCanvas3D;
  148.     Function MultiLineTextWidth(S:String; Var NumLines:Integer):Integer;
  149.     Procedure SetMargin(Index,Value:Integer);
  150.     Procedure Loaded; override;
  151.     procedure WMEraseBkgnd(var Message: TWmEraseBkgnd); message WM_ERASEBKGND;
  152.     procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
  153.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  154.     Procedure InternalDraw(Const UserRectangle:TRect); virtual; abstract;
  155.     procedure Paint; override;
  156.   public
  157.     AutoRepaint  : Boolean;  { when False, the Chart does not refresh }
  158.     CancelMouse  : Boolean;  { when True, the Chart does not finish mouse events }
  159.  
  160.     { not possible to make a property, because D1 }
  161.     ChartRect    : TRect; { the rectangle bounded by axes in pixels }
  162.     PrintMargins : TRect; { the percent of paper printer margins }
  163.  
  164.     Constructor Create(AOwner: TComponent); override;
  165.     Destructor Destroy; override;
  166.  
  167.     Procedure Assign(Source:TPersistent); override;
  168.     Procedure CalcMetaBounds( Var R:TRect; Const AChartRect:TRect;
  169.                               Var WinWidth,WinHeight,ViewWidth,ViewHeight:Longint);
  170.     Function CalcProportionalMargins:TRect;
  171.     Function CanClip:Boolean;
  172.     Procedure CanvasChanged(Sender:TObject); virtual;
  173.     Function ChartPrintRect:TRect;
  174.     Procedure CheckPenWidth(APen:TPen);
  175.     Procedure CopyToClipboardBitmap;
  176.     Procedure CopyToClipboardMetafile(Enhanced:Boolean);
  177.     Function TeeCreateBitmap(ABackColor:TColor; Const Rect:TRect):TBitmap;
  178.     Procedure Draw(UserCanvas:TCanvas; Const UserRect:TRect); virtual;
  179.     Procedure DrawPanelBevels(Rect:TRect); virtual;
  180.     Procedure DrawToMetaCanvas(ACanvas:TCanvas; Const Rect:TRect);
  181.     Procedure DrawZoomRectangle;
  182.  
  183.     Procedure FontCanvas(SourceFont:TFont); virtual;
  184.     Function GetCursorPos:TPoint;
  185.     Function GetRectangle:TRect; virtual;
  186.     procedure Invalidate; override;
  187.     Function IsScreenHighColor:Boolean;
  188.  
  189.     Procedure Print;
  190.     Procedure PrintLandscape;
  191.     Procedure PrintOrientation(AOrientation:TPrinterOrientation);
  192.     Procedure PrintPartial(Const PrinterRect:TRect);
  193.     Procedure PrintPartialCanvas( PrintCanvas:TCanvas;
  194.                                   Const PrinterRect:TRect);
  195.     Procedure PrintPortrait;
  196.     Procedure PrintRect(Const R:TRect);
  197.     Procedure SaveToBitmapFile(Const FileName:String);
  198.     Procedure SaveToMetafile(Const FileName:String);
  199.     Procedure SaveToMetafileEnh(Const FileName:String);
  200.     Procedure SaveToMetafileRect( Enhanced:Boolean; Const FileName:String;
  201.                                   Const Rect:TRect );
  202.     Procedure SetBooleanProperty(Var Variable:Boolean; Value:Boolean);
  203.     Procedure SetBrushCanvas( AColor:TColor; APattern:TBrushStyle;
  204.                               ABackColor:TColor);
  205.     Procedure SetColorProperty(Var Variable:TColor; Value:TColor);
  206.     Procedure SetDoubleProperty(Var Variable:Double; Const Value:Double);
  207.     Procedure SetLongintProperty(Var Variable:Longint; Value:Longint);
  208.     Procedure SetIntegerProperty(Var Variable:Integer; Value:Integer);
  209.     Procedure SetInternalCanvas(NewCanvas:TCanvas3D);
  210.     Procedure SetStringProperty(Var Variable:String; Const Value:String);
  211.     Procedure ReCalcWidthHeight;
  212.     Function  TeeCreateMetafile(Enhanced:Boolean; Const Rect:TRect):TMetafile;
  213.  
  214.     { public properties }
  215.     property ApplyZOrder:Boolean read FApplyZOrder write FApplyZOrder;
  216.     property BufferedDisplay:Boolean read GetBufferedDisplay
  217.                                      write SetBufferedDisplay;
  218.     property Canvas:TCanvas3D read InternalCanvas write SetInternalCanvas;
  219.     property ChartBounds:TRect read FChartBounds;
  220.     property ChartHeight:Integer read FChartHeight;
  221.     property ChartWidth:Integer read FChartWidth;
  222.     property ChartXCenter:Integer read FChartXCenter;
  223.     property ChartYCenter:Integer read FChartYCenter;
  224.     property DelphiCanvas:TCanvas read FDelphiCanvas;
  225.     property Height3D:Integer read FHeight3D write FHeight3D;
  226.     property IPanning:TZoomPanningRecord read FPanning;
  227.     property IZoom:TZoomPanningRecord read FZoom;
  228.     property OriginalCursor:TCursor read FOriginalCursor write FOriginalCursor;
  229.     property Printing:Boolean read FPrinting write FPrinting;
  230.     property Width3D:Integer read FWidth3D write FWidth3D;
  231.  
  232.     property PrintResolution:Integer read FPrintResolution
  233.                                      write FPrintResolution default TeeNormalPrintDetail;
  234.     { to be published properties }
  235.     property Chart3DPercent:Integer read F3DPercent write Set3DPercent
  236.                                     default TeeDef3DPercent;
  237.     property MarginLeft:Integer   index 0 read GetMargin write SetMargin default TeeDefHorizMargin;
  238.     property MarginTop:Integer    index 1 read GetMargin write SetMargin default TeeDefVerticalMargin;
  239.     property MarginRight:Integer  index 2 read GetMargin write SetMargin default TeeDefHorizMargin;
  240.     property MarginBottom:Integer index 3 read GetMargin write SetMargin default TeeDefVerticalMargin;
  241.     property Monochrome:Boolean read GetMonochrome write SetMonochrome default False;
  242.     property PrintProportional:Boolean read FPrintProportional
  243.                                        write FPrintProportional default True;
  244.     property View3D:Boolean read FView3D write SetView3D default True;
  245.     property View3DOptions:TView3DOptions read FView3DOptions write SetView3DOptions;
  246.  
  247.     { TPanel properties }
  248.     property Align;
  249.     property BevelInner;
  250.     property BevelOuter;
  251.     property BevelWidth;
  252.     property BorderWidth;
  253.     property BorderStyle;
  254.     property Color;
  255.     property DragCursor;
  256.     property DragMode;
  257.     property Enabled;
  258.     property ParentColor;
  259.     property ParentShowHint;
  260.     property PopupMenu;
  261.     property ShowHint;
  262.     property TabOrder;
  263.     property TabStop;
  264.     property Visible;
  265.     
  266.     property OnMouseDown;
  267.     property OnMouseMove;
  268.     property OnMouseUp;
  269.   published
  270.   end;
  271.  
  272.   TPanningMode=(pmNone,pmHorizontal,pmVertical,pmBoth);
  273.  
  274.   TCustomTeeGradient=class(TPersistent)
  275.   private
  276.     FDirection : TGradientDirection;
  277.     FEndColor  : TColor;
  278.     FOwner     : TCustomTeePanel;
  279.     FStartColor: TColor;
  280.     FVisible   : Boolean;
  281.     Procedure SetDirection(Value:TGradientDirection);
  282.     Procedure SetEndColor(Value:TColor);
  283.     Procedure SetStartColor(Value:TColor);
  284.     Procedure SetVisible(Value:Boolean);
  285.   protected
  286.   public
  287.     Constructor Create(AOwner:TCustomTeePanel);
  288.     Procedure Assign(Source:TPersistent); override;
  289.     property Owner:TCustomTeePanel read FOwner write FOwner; { write for Tree }
  290.     { to published }
  291.     property Direction:TGradientDirection read FDirection write SetDirection default gdTopBottom;
  292.     property EndColor:TColor read FEndColor write SetEndColor default clYellow;
  293.     property StartColor:TColor read FStartColor write SetStartColor default clWhite;
  294.     property Visible:Boolean read FVisible write SetVisible default False;
  295.   end;
  296.  
  297.   TChartGradient=class(TCustomTeeGradient)
  298.   published
  299.     property Direction;
  300.     property EndColor;
  301.     property StartColor;
  302.     property Visible;
  303.   end;
  304.  
  305.   TCustomTeePanelExtended=class(TCustomTeePanel)
  306.   private
  307.     FAnimatedZoomSteps : Integer;
  308.     FAnimatedZoom      : Boolean;
  309.     FAllowZoom         : Boolean;
  310.     FAllowPanning      : TPanningMode;
  311.     FBackImage         : TPicture;
  312.     FBackImageMode     : TTeeBackImageMode;
  313.     FGradient          : TChartGradient;
  314.     FZoomed            : Boolean;
  315.  
  316.     Procedure SetAnimatedZoom(Value:Boolean);
  317.     Procedure SetAnimatedZoomSteps(Value:Integer);
  318.     procedure SetBackImage(Value:TPicture);
  319.     procedure SetBackImageMode(Value:TTeeBackImageMode);
  320.     Procedure SetGradient(Value:TChartGradient);
  321.   protected
  322.     FOnAfterDraw       : TNotifyEvent;
  323.     FOnScroll          : TNotifyEvent;
  324.     FOnUndoZoom        : TNotifyEvent;
  325.     FOnZoom            : TNotifyEvent;
  326.     function GetPalette: HPALETTE; override;    { override the method }
  327.     procedure DrawBitmap(Rect:TRect; Z:Integer);
  328.     Procedure DrawImage(Const R:TRect); virtual;
  329.     procedure FillPanelRect(Const Rect:TRect); virtual;
  330.     procedure PanelPaint(Const UserRect:TRect); virtual;
  331.   public
  332.     Constructor Create(AOwner:TComponent); override;
  333.     Destructor Destroy; override;
  334.  
  335.     Procedure Assign(Source:TPersistent); override;
  336.     procedure UndoZoom; virtual;
  337.     property Zoomed:Boolean read FZoomed write FZoomed;
  338.  
  339.     property AllowPanning:TPanningMode read FAllowPanning
  340.                        write FAllowPanning default pmBoth;
  341.     property AllowZoom:Boolean read FAllowZoom write FAllowZoom default True;
  342.     property AnimatedZoom:Boolean read FAnimatedZoom
  343.                   write SetAnimatedZoom default False;
  344.     property AnimatedZoomSteps:Integer read FAnimatedZoomSteps
  345.                        write SetAnimatedZoomSteps default 8;
  346.     property BackImage:TPicture read FBackImage write SetBackImage;
  347.     property BackImageMode:TTeeBackImageMode read FBackImageMode
  348.                          write SetBackImageMode
  349.                          default pbmStretch;
  350.     property Gradient:TChartGradient read FGradient write SetGradient;
  351.     { events }
  352.     property OnAfterDraw:TNotifyEvent read FOnAfterDraw write FOnAfterDraw;
  353.     property OnScroll:TNotifyEvent read FOnScroll write FOnScroll;
  354.     property OnUndoZoom:TNotifyEvent read FOnUndoZoom write FOnUndoZoom;
  355.     property OnZoom:TNotifyEvent read FOnZoom write FOnZoom;
  356.   end;
  357.  
  358.   TDraw3DPaintEvent=procedure(Sender:TObject; Const Rect:TRect) of object;
  359.  
  360.   TDraw3D=class(TCustomTeePanelExtended)
  361.   private
  362.     FOnPaint:TDraw3DPaintEvent;
  363.   protected
  364.     Procedure InternalDraw(Const UserRectangle:TRect); override;
  365.   published
  366.     { TCustomTeePanelExtended properties }
  367.     property BackImage;
  368.     property BackImageMode;
  369.     property Gradient;
  370.     property OnAfterDraw;
  371.  
  372.     { TCustomTeePanel properties }
  373.     property BufferedDisplay;
  374.     property MarginLeft;
  375.     property MarginTop;
  376.     property MarginRight;
  377.     property MarginBottom;
  378.     property Monochrome;
  379.     property PrintProportional;
  380.     property PrintResolution;
  381.     property View3D;
  382.     property View3DOptions;
  383.     property OnPaint:TDraw3DPaintEvent read FOnPaint write FOnPaint;
  384.  
  385.     { TPanel properties }
  386.     property Align;
  387.     property BevelInner;
  388.     property BevelOuter;
  389.     property BevelWidth;
  390.     property BorderWidth;
  391.     property BorderStyle;
  392.     property Color;
  393.     property DragCursor;
  394.     property DragMode;
  395.     property Enabled;
  396.     property ParentColor;
  397.     property ParentShowHint;
  398.     property PopupMenu;
  399.     property ShowHint;
  400.     property TabOrder;
  401.     property TabStop;
  402.     property Visible;
  403.  
  404.     { TPanel events }
  405.     property OnClick;
  406.     property OnDblClick;
  407.     property OnDragDrop;
  408.     property OnDragOver;
  409.     property OnEndDrag;
  410.     property OnEnter;
  411.     property OnExit;
  412.     property OnMouseDown;
  413.     property OnMouseMove;
  414.     property OnMouseUp;
  415.     property OnResize;
  416.     {$IFDEF D3}
  417.     property OnStartDrag;
  418.     {$ENDIF}
  419.   end;
  420.  
  421.   TChartFontObject=class(TPersistent)
  422.   private
  423.     FParentChart : TCustomTeePanel;
  424.   protected
  425.     FFont : TFont;
  426.     Procedure SetFont(Value:TFont);
  427.     Function IsFontStored:Boolean;
  428.   public
  429.     Constructor Create(AOwner: TCustomTeePanel);
  430.     Destructor Destroy; override;
  431.     Procedure Assign(Source:TPersistent); override;
  432.     Procedure Repaint;
  433.   { to be published }
  434.     property Font:TFont read FFont write SetFont stored IsFontStored;
  435.     property ParentChart:TCustomTeePanel read FParentChart;
  436.   end;
  437.  
  438. { returns one of the sample colors in ColorPalette constant array }
  439. Function GetDefaultColor(t:Longint):TColor;
  440.  
  441. Function GetScreenLogPixels:Integer;
  442. {$IFDEF D3}
  443. Procedure CheckJapaneseFontSize(Var ASize:Integer);
  444. {$ENDIF}
  445. Function IsDefaultFont(AFont:TFont):Boolean;
  446. Function CreateDefaultFont(ChangedEvent:TNotifyEvent):TFont;
  447. Function GetDefaultFontSize:Integer;
  448. Function GetDefaultFontName:String;
  449.  
  450. Function DateTimeDefaultFormat(Const AStep:Double):String;
  451.  
  452. Function DaysInMonth(Year,Month:Word):Word;
  453.  
  454. Function FindDateTimeStep(Const StepValue:Double):TDateTimeStep;
  455. Function NextDateTimeStep(Const AStep:Double):Double;
  456.  
  457. { returns the associated filename extension for images (BMP, WMF, etc) }
  458. Function TeeGetImageExtension(Index:Longint):String;
  459.  
  460. { finds ACursor and returns its name, including crTeeHand cursor }
  461. Function TeeCursorToIdent(ACursor:Longint; Var AName:String):Boolean;
  462. { finds AName and returns its Cursor, including TeeHand cursor }
  463. Function TeeIdentToCursor(Const AName:String; Var ACursor:Longint):Boolean;
  464.  
  465. { Returns True if point T is over line:  P --> Q }
  466. Function PointInLine(Const P:TPoint; px,py,qx,qy:Integer):Boolean;
  467.  
  468. { Returns True if point T is over (more or less "Tolerance" pixels)
  469.   line:  P --> Q }
  470. Function PointInLineTolerance(Const P:TPoint; px,py,qx,qy,TolerancePixels:Integer):Boolean;
  471.  
  472. { Returns True if point P is inside Poly polygon }
  473. Function PointInPolygon(Const P:TPoint; Const Poly:Array of TPoint):Boolean;
  474.  
  475. { Returns True if point P is inside the vert triangle of x0y0, midxY1, x1y0 }
  476. Function PointInTriangle(Const P:TPoint; X0,X1,Y0,Y1:Integer):Boolean;
  477.  
  478. { Returns True if point P is inside the horiz triangle of x0y0, x1midY, x0y0 }
  479. Function PointInHorizTriangle(Const P:TPoint; Y0,Y1,X0,X1:Integer):Boolean;
  480.  
  481. { Returns True if point P is inside the ellipse bounded by Rect }
  482. Function PointInEllipse(Const P:TPoint; Const Rect:TRect):Boolean;
  483.  
  484. { Replaces all ocurrences of "Separator" in string "St" with
  485.   #13 (TeeLineSeparator constant)  }
  486. Procedure TeeSplitInLines(Var St:String; Const Separator:String);
  487.  
  488. { Returns 1 + how many times "TeeLineSeparator #13" is found
  489.   inside string St parameter }
  490. Function TeeNumTextLines(St:String):Integer;
  491.  
  492. {$IFNDEF D3}
  493. Function AnsiPos(Const SubStr,St:String):Integer;
  494. {$ENDIF}
  495.  
  496. Function DelphiToLocalFormat(Const Format:String):String;
  497. Function LocalToDelphiFormat(Const Format:String):String;
  498. Procedure EnableControls(Enable:Boolean; Const ControlArray:Array of TControl);
  499.  
  500. { raises an exception if Value <0 or >360 }
  501. Procedure TeeCheckAngle(Value:Integer; Const Description:String);
  502.  
  503. { Round "ADate" to the nearest "AStep" value }
  504. Function TeeRoundDate(Const ADate:TDateTime; AStep:TDateTimeStep):TDateTime;
  505.  
  506. { Increment or Decrement "Value", for DateTime and not-DateTime }
  507. Procedure TeeDateTimeIncrement( IsDateTime:Boolean;
  508.                                 Increment:Boolean;
  509.                                 Var Value:Double;
  510.                                 Const AnIncrement:Double;
  511.                                 tmpWhichDateTime:TDateTimeStep);
  512.  
  513. { Load the ABitmap resource for AClass.ClassName }
  514. Procedure TeeGetClassNameBitmap(AClass:TComponent; ABitmap:TBitmap);
  515.  
  516. { Returns a "good" value, bigger than "OldStep", as 2..5..10..etc }
  517. Function TeeNextStep(Const OldStep:Double):Double;
  518.  
  519. { returns number of sections in St string separated by ";" }
  520. Function TeeNumFields(St:String):Integer;
  521.  
  522. { returns the index-th section in St string separated by ";" }
  523. Function TeeExtractField(St:String; Index:Integer):String;
  524.  
  525. { Returns a valid component name, for Delphi 1, 2, 3 & 4 and C++ 1 and 3 }
  526. Function TeeGetUniqueName(AOwner:TComponent; Const AStartName:String):String;
  527.  
  528. implementation
  529.  
  530. Uses DsgnIntf,TeeConst;
  531.  
  532. {.$DEFINE MONITOR_REDRAWS}
  533.  
  534. {$IFDEF MONITOR_REDRAWS}
  535. Const RedrawCount:Integer=0;
  536. {$ENDIF}
  537.  
  538. {$IFDEF D1}
  539. {$R TEERESOU.R16}
  540. {$ELSE}
  541. {$R TEERESOU.RES}
  542. {$ENDIF}
  543.  
  544. Function DaysInMonth(Year,Month:Word):Word;
  545. Const DaysMonths:Array[1..12] of Byte=(31,28,31,30,31,30,31,31,30,31,30,31);
  546. Begin
  547.   result:=DaysMonths[Month];
  548.   if (Month=2) and
  549.   {$IFDEF D4}
  550.      IsLeapYear(Year)
  551.   {$ELSE}
  552.      (Year mod 4=0) and
  553.      ( (Year mod 100<>0) or (Year mod 400=0) )
  554.   {$ENDIF}
  555.      then Inc(result);
  556. End;
  557.  
  558. Function DateTimeDefaultFormat(Const AStep:Double):String;
  559. Begin
  560.   if AStep<=1 then result:=ShortTimeFormat
  561.               else result:=ShortDateFormat;
  562. end;
  563.  
  564. Function NextDateTimeStep(Const AStep:Double):Double;
  565. var t:TDateTimeStep;
  566. Begin
  567.   for t:=Pred(dtOneYear) downto dtOneSecond do
  568.   if AStep>=DateTimeStep[t] then
  569.   Begin
  570.     result:=DateTimeStep[Succ(t)];
  571.     exit;
  572.   end;
  573.   result:=DateTimeStep[dtOneYear];
  574. end;
  575.  
  576. Function FindDateTimeStep(Const StepValue:Double):TDateTimeStep;
  577. var t:TDateTimeStep;
  578. begin
  579.   for t:=pred(High(DateTimeStep)) downto low(DateTimeStep) do
  580.   begin
  581.     if Abs(DateTimeStep[t]-StepValue)<DateTimeStep[dtOneSecond] then
  582.     begin
  583.       result:=t;
  584.       exit;
  585.     end;
  586.   end;
  587.   result:=dtNone;
  588. end;
  589.  
  590. Function MaxDouble(Const a,b:Double):Double;
  591. begin
  592.   if a>b then result:=a else result:=b;
  593. end;
  594.  
  595. Function MinDouble(Const a,b:Double):Double;
  596. begin
  597.   if a<b then result:=a else result:=b;
  598. end;
  599.  
  600. Function MaxLong(a,b:Longint):Longint;
  601. begin
  602.   if a>b then result:=a else result:=b;
  603. end;
  604.  
  605. Function MinLong(a,b:Longint):Longint;
  606. begin
  607.   if a>b then result:=b else result:=a;
  608. end;
  609.  
  610. Procedure SwapLongint(Var a,b:Longint);
  611. var tmp:Longint;
  612. Begin
  613.   Tmp:=a;  a:=b;  b:=Tmp;
  614. End;
  615.  
  616. Procedure SwapDouble(Var a,b:Double);
  617. var tmp:Double;
  618. begin
  619.   tmp:=a;  a:=b;  b:=tmp;
  620. end;
  621.  
  622. Procedure SwapInteger(Var a,b:Integer);
  623. var tmp:Integer;
  624. Begin
  625.   tmp:=a; a:=b; b:=tmp;
  626. end;
  627.  
  628. Function GetScreenLogPixels:Integer;
  629. var DC:HDC;
  630. Begin
  631.   DC:=GetDC(0);
  632.   Result:=GetDeviceCaps(DC,LOGPIXELSY);
  633.   ReleaseDC(0,DC);
  634. end;
  635.  
  636. {$IFDEF D3}
  637. Procedure CheckJapaneseFontSize(Var ASize:Integer);
  638. begin
  639.   if (ASize=8) and (SysLocale.PriLangID=LANG_JAPANESE) then
  640.       ASize:=-MulDiv(DefFontData.Height,72,GetScreenLogPixels);
  641. end;
  642. {$ENDIF}
  643.  
  644. Function GetDefaultFontSize:Integer;
  645. Begin
  646.   result:=StrToInt(TeeMsg_DefaultFontSize);
  647. {$IFDEF D3}
  648.   CheckJapaneseFontSize(result);
  649. {$ENDIF}
  650. end;
  651.  
  652. Function GetDefaultFontName:String;
  653. Begin
  654.   result:=TeeMsg_DefaultFontName;
  655. {$IFDEF D3}
  656.   if (result='Arial') and (SysLocale.PriLangID=LANG_JAPANESE) then  { <-- do not translate }
  657.       result:=DefFontData.Name;
  658. {$ENDIF}
  659. end;
  660.  
  661. Function IsDefaultFont(AFont:TFont):Boolean;
  662. Begin
  663.   With AFont do
  664.     result:= (Size=GetDefaultFontSize) and (Name=GetDefaultFontName) and
  665.              (Color=clBlack) and (Style=[]) {$IFDEF D3}and (CharSet=DEFAULT_CHARSET){$ENDIF};
  666. end;
  667.  
  668. Function CreateDefaultFont(ChangedEvent:TNotifyEvent):TFont;
  669. Begin
  670.   result:=TFont.Create;
  671.   With result do
  672.   begin
  673.     Name:=GetDefaultFontName;
  674.     Size:=GetDefaultFontSize;
  675.     Color:=clBlack;
  676.     Style:=[];
  677.     OnChange:=ChangedEvent;
  678.   end;
  679. end;
  680.  
  681. Function GetDefaultColor(t:Longint):TColor;
  682. Begin
  683.   result:=ColorPalette[1+(t mod MaxDefaultColors)];
  684. end;
  685.  
  686. Procedure TeeCheckAngle(Value:Integer; Const Description:String);
  687. Begin
  688.   if (Value<0) or (Value>360) then
  689.      Raise ChartException.CreateFmt(TeeMsg_Angle,[Description]);
  690. end;
  691.  
  692. { TCustomTeePanel }
  693. Constructor TCustomTeePanel.Create(AOwner: TComponent);
  694. begin
  695.   InternalCanvas:=nil;
  696.   inherited Create(AOwner);
  697.   ControlStyle:=ControlStyle-[csSetCaption];
  698.   Width := 400;
  699.   Height:= 250;
  700.   F3DPercent   :=TeeDef3DPercent;
  701.   AutoRepaint :=False;
  702.   FApplyZOrder :=True;
  703.   FDelphiCanvas:=inherited Canvas;
  704.   FView3D      :=True;
  705.   FView3DOptions:=TView3DOptions.Create(Self);
  706.   InternalCanvas:=TTeeCanvas3D.Create;
  707.   InternalCanvas.ReferenceCanvas:=FDelphiCanvas;
  708.   FMargins:=Rect(TeeDefHorizMargin,TeeDefVerticalMargin,TeeDefHorizMargin,TeeDefVerticalMargin);
  709.   FPrinting:=False;
  710.   FPrintProportional:=True;
  711.   FPrintResolution:=TeeNormalPrintDetail;
  712.   PrintMargins:=Rect( TeeDefault_PrintMargin,TeeDefault_PrintMargin,
  713.                       TeeDefault_PrintMargin,TeeDefault_PrintMargin);
  714.   FOriginalCursor:=Cursor;
  715.   FZoom   :=TZoomPanningRecord.Create;
  716.   FPanning:=TZoomPanningRecord.Create;
  717.   if TeeEraseBack then TeeEraseBack:=not (csDesigning in ComponentState);
  718.   AutoRepaint:=True;
  719. end;
  720.  
  721. Destructor TCustomTeePanel.Destroy;
  722. Begin
  723.   InternalCanvas.Free;
  724.   InternalCanvas:=nil;
  725.   FView3DOptions.Free;
  726.   FZoom.Free;
  727.   FPanning.Free;
  728.   inherited Destroy;
  729. end;
  730.  
  731. Procedure TCustomTeePanel.CanvasChanged(Sender:TObject);
  732. Begin
  733.   Invalidate;
  734. end;
  735.  
  736. procedure TCustomTeePanel.SetView3DOptions(Value:TView3DOptions);
  737. begin
  738.   FView3DOptions.Assign(Value);
  739. end;
  740.  
  741. procedure TCustomTeePanel.SetView3D(Value:Boolean);
  742. Begin
  743.   SetBooleanProperty(FView3D,Value);
  744. end;
  745.  
  746. Procedure TCustomTeePanel.Draw(UserCanvas:TCanvas; Const UserRect:TRect);
  747. Var tmpW,tmpH:Longint;
  748. Begin
  749.   FChartBounds:=InternalCanvas.InitWindow(UserCanvas,FView3DOptions,Color,FView3D,UserRect);
  750.   RectSize(FChartBounds,tmpW,tmpH);
  751.   With FChartBounds do
  752.        ChartRect:=Rect( Left  + BorderWidth + MulDiv(MarginLeft,tmpW,100),
  753.                         Top   + BorderWidth + MulDiv(MarginTop,tmpH,100),
  754.                         Right - BorderWidth - MulDiv(MarginRight,tmpW,100),
  755.                         Bottom- BorderWidth - MulDiv(MarginBottom,tmpH,100) );
  756.   RecalcWidthHeight;
  757.   InternalDraw(FChartBounds);
  758.  
  759. {$IFDEF MONITOR_REDRAWS}
  760.   Inc(RedrawCount);
  761.   InternalCanvas.TextOut(0,0,IntToStr(RedrawCount));
  762. {$ENDIF}
  763.   InternalCanvas.ShowImage(UserCanvas,FDelphiCanvas,UserRect);
  764. end;
  765.  
  766. procedure TCustomTeePanel.Paint;
  767. begin
  768.   if (not FPrinting) and (not InternalCanvas.ReDrawBitmap) then
  769.      Draw(FDelphiCanvas,GetClientRect);
  770. end;
  771.  
  772. Function TCustomTeePanel.TeeCreateMetafile( Enhanced:Boolean; Const Rect:TRect ):TMetafile;
  773. {$IFNDEF D1}
  774. var tmpCanvas:TMetafileCanvas;
  775. begin
  776.   result:=TMetafile.Create;
  777.   { bug in D3.02 ... graphics.pas metafile reduces width/height.
  778.     Workaround:
  779.        - Use D3.01 graphics.pas?
  780.   }
  781.   result.Width :=MaxLong(1,(Rect.Right-Rect.Left)-1);
  782.   result.Height:=MaxLong(1,(Rect.Bottom-Rect.Top)-1);
  783.   result.Enhanced:=Enhanced;
  784.   tmpCanvas:=TMetafileCanvas.Create(result,0);
  785.   try
  786.     DrawToMetaCanvas(tmpCanvas,Rect);
  787.   finally
  788.     tmpCanvas.Free;
  789.   end;
  790. end;
  791. {$ELSE}
  792. Var tmpHandle:HMETAFILE;
  793.     tmpCanvas:TCanvas;
  794. begin
  795.   tmpHandle:=CreateMetafile(nil);
  796.   tmpCanvas:=TCanvas.Create;
  797.   tmpCanvas.Handle:=tmpHandle;
  798.   try
  799.     DrawToMetaCanvas(tmpCanvas,Rect);
  800.   finally
  801.     tmpCanvas.Free;
  802.   end;
  803.   result:=TMetafile.Create;
  804.   With result do
  805.   begin
  806.     Handle:=CloseMetafile(tmpHandle);
  807.     Inch:=Screen.PixelsPerInch;
  808.     Width :=MaxLong(1,(Rect.Right-Rect.Left)-1);
  809.     Height:=MaxLong(1,(Rect.Bottom-Rect.Top)-1);
  810.   end;
  811. end;
  812. {$ENDIF}
  813.  
  814. {$IFNDEF D1}
  815. {$HINTS OFF}
  816. {$ENDIF}
  817. Procedure TCustomTeePanel.SetBrushCanvas( AColor:TColor; APattern:TBrushStyle;
  818.                                           ABackColor:TColor);
  819. Const BrushColors:Array[Boolean] of TColor=(clBlack,clWhite);
  820. Var tmp:HBrush;
  821. begin
  822.   with Canvas do
  823.   begin
  824.     if (APattern<>bsSolid) and (AColor=ABackColor) then
  825.        Brush.Color:=BrushColors[ABackColor=clBlack]
  826.     else
  827.        Brush.Color:=AColor;
  828.     Brush.Style:=APattern;
  829.     tmp:=Brush.Handle; { <-- force brush creation }
  830.     if APattern=bsSolid then BackMode:=cbmTransparent
  831.     else
  832.     begin
  833.       BackMode:=cbmOpaque;
  834.       BackColor:=ColorToRGB(ABackColor);
  835.     end;
  836.   end;
  837. end;
  838. {$IFNDEF D1}
  839. {$HINTS ON}
  840. {$ENDIF}
  841.  
  842. Procedure TCustomTeePanel.FontCanvas(SourceFont:TFont);
  843. Begin
  844.   With InternalCanvas.Font do
  845.   begin
  846.     SourceFont.PixelsPerInch:=PixelsPerInch;
  847.     Assign(SourceFont);
  848.   end;
  849. End;
  850.  
  851. Function TCustomTeePanel.IsScreenHighColor:Boolean;
  852. Begin
  853.   With InternalCanvas do
  854.     result:= GetDeviceCaps(Handle,BITSPIXEL)*
  855.              GetDeviceCaps(Handle,PLANES)>=15;
  856. End;
  857.  
  858. Function TCustomTeePanel.CanClip:Boolean;
  859. begin
  860.   result:=((not Printing) and (not Canvas.Metafiling)) or
  861.           (Printing and TeeClipWhenPrinting) or
  862.           (Canvas.Metafiling and TeeClipWhenMetafiling)
  863. end;
  864.  
  865. Procedure TCustomTeePanel.Set3DPercent(Value:Integer);
  866. Const Max3DPercent = 100;
  867.       Min3DPercent = 1;
  868. Begin
  869.   if (Value<Min3DPercent) or (Value>Max3DPercent) then
  870.      Raise ChartException.CreateFmt(TeeMsg_3DPercent,[Min3DPercent,Max3DPercent])
  871.   else
  872.     SetIntegerProperty(F3DPercent,Value);
  873. end;
  874.  
  875. Procedure TCustomTeePanel.SetLongintProperty(Var Variable:Longint; Value:Longint);
  876. Begin
  877.   if Variable<>Value then
  878.   begin
  879.     Variable:=Value; Invalidate;
  880.   end;
  881. end;
  882.  
  883. Procedure TCustomTeePanel.SetStringProperty(Var Variable:String; Const Value:String);
  884. Begin
  885.   if Variable<>Value then
  886.   begin
  887.     Variable:=Value; Invalidate;
  888.   end;
  889. end;
  890.  
  891. Procedure TCustomTeePanel.SetDoubleProperty(Var Variable:Double; Const Value:Double);
  892. begin
  893.   if Variable<>Value then
  894.   begin
  895.     Variable:=Value; Invalidate;
  896.   end;
  897. end;
  898.  
  899. Procedure TCustomTeePanel.SetColorProperty(Var Variable:TColor; Value:TColor);
  900. Begin
  901.   if Variable<>Value then
  902.   begin
  903.     Variable:=Value; Invalidate;
  904.   end;
  905. end;
  906.  
  907. Procedure TCustomTeePanel.SetBooleanProperty(Var Variable:Boolean; Value:Boolean);
  908. Begin
  909.   if Variable<>Value then
  910.   begin
  911.     Variable:=Value; Invalidate;
  912.   end;
  913. end;
  914.  
  915. Procedure TCustomTeePanel.SetIntegerProperty(Var Variable:Integer; Value:Integer);
  916. Begin
  917.   if Variable<>Value then
  918.   begin
  919.     Variable:=Value; Invalidate;
  920.   end;
  921. end;
  922.  
  923. Procedure TCustomTeePanel.Loaded;
  924. begin
  925.   inherited Loaded;
  926.   FOriginalCursor:=Cursor;
  927. end;
  928.  
  929. procedure TCustomTeePanel.CMMouseLeave(var Message: TMessage);
  930. begin
  931.   Cursor:=FOriginalCursor;
  932.   FPanning.Active:=False;
  933.   inherited;
  934. end;
  935.  
  936. procedure TCustomTeePanel.WMGetDlgCode(var Message: TWMGetDlgCode);
  937. begin
  938.   inherited;
  939.   Message.Result:=Message.Result or DLGC_WANTARROWS;
  940. end;
  941.  
  942. procedure TCustomTeePanel.WMEraseBkgnd(var Message: TWmEraseBkgnd);
  943. Begin
  944.   if TeeEraseBack then Inherited;
  945.   Message.Result:=1;
  946. End;
  947.  
  948. procedure TCustomTeePanel.Invalidate;
  949. begin
  950.   if AutoRepaint then
  951.   begin
  952.     if Assigned(InternalCanvas) then InternalCanvas.Invalidate;
  953.     inherited Invalidate;
  954.   end;
  955. end;
  956.  
  957. Function TCustomTeePanel.MultiLineTextWidth(S:String; Var NumLines:Integer):Integer;
  958. var i : Integer;
  959. begin
  960.   i:=Pos(TeeLineSeparator,s);
  961.   if i=0 then  { optimized for speed }
  962.   begin
  963.     result:=Canvas.TextWidth(s);
  964.     NumLines:=1;
  965.   end
  966.   else
  967.   begin
  968.     result:=0;
  969.     NumLines:=0;
  970.     While i>0 do
  971.     begin
  972.       result:=MaxLong(result,Canvas.TextWidth(Copy(s,1,i-1)));
  973.       Inc(NumLines);
  974.       Delete(s,1,i);
  975.       i:=Pos(TeeLineSeparator,s);
  976.     end;
  977.     if s<>'' then
  978.     begin
  979.       result:=MaxLong(result,Canvas.TextWidth(s));
  980.       Inc(NumLines);
  981.     end;
  982.   end;
  983. end;
  984.  
  985. Function TCustomTeePanel.GetMargin(Index:Integer):Integer;
  986. Begin
  987.   with FMargins do
  988.   Case Index of
  989.     0: result:=Left;
  990.     1: result:=Top;
  991.     2: result:=Right;
  992.   else
  993.   { 3:} result:=Bottom;
  994.   end;
  995. end;
  996.  
  997. Procedure TCustomTeePanel.SetMargin(Index,Value:Integer);
  998. Begin
  999.   with FMargins do
  1000.   Case Index of
  1001.     0: SetIntegerProperty(Left,Value);
  1002.     1: SetIntegerProperty(Top,Value);
  1003.     2: SetIntegerProperty(Right,Value);
  1004.   else SetIntegerProperty(Bottom,Value);
  1005.   end;
  1006. end;
  1007.  
  1008. Function TCustomTeePanel.GetBufferedDisplay:Boolean;
  1009. begin
  1010.   result:=InternalCanvas.UseBuffer;
  1011. end;
  1012.  
  1013. Procedure TCustomTeePanel.SetBufferedDisplay(Value:Boolean);
  1014. begin
  1015.   InternalCanvas.UseBuffer:=Value;
  1016. end;
  1017.  
  1018. Procedure TCustomTeePanel.SetInternalCanvas(NewCanvas:TCanvas3D);
  1019. begin
  1020.   if Assigned(NewCanvas) then
  1021.   begin
  1022.     NewCanvas.ReferenceCanvas:=FDelphiCanvas;
  1023.     if Assigned(InternalCanvas) then
  1024.     begin
  1025.       AutoRepaint:=False;
  1026.       NewCanvas.Assign(InternalCanvas);
  1027.       AutoRepaint:=True;
  1028.       InternalCanvas.Free;
  1029.     end;
  1030.     InternalCanvas:=NewCanvas;
  1031.     Repaint;
  1032.   end;
  1033. end;
  1034.  
  1035. procedure TCustomTeePanel.RecalcWidthHeight;
  1036. Begin
  1037.   With ChartRect do
  1038.   begin
  1039.     if Left<FChartBounds.Left then Left:=FChartBounds.Left;
  1040.     if Top<FChartBounds.Top then Top:=FChartBounds.Top;
  1041.     if Right<Left then Right:=Left+1 else
  1042.     if Right=Left then Right:=Left+Width;
  1043.     if Bottom<Top then Bottom:=Top+1 else
  1044.     if Bottom=Top then Bottom:=Top+Height;
  1045.     FChartWidth  :=Right-Left;
  1046.     FChartHeight :=Bottom-Top;
  1047.     FChartXCenter:=(Left+Right) div 2;
  1048.     FChartYCenter:=(Top+Bottom) div 2;
  1049.   end;
  1050. end;
  1051.  
  1052. procedure TCustomTeePanel.DrawZoomRectangle;
  1053. Begin
  1054.   With InternalCanvas do
  1055.   Begin
  1056.     With Pen do
  1057.     begin
  1058.       Color:=ColorToRGB(Self.Color);
  1059.       if Color=clWhite then Color:=clBlack;  { when color is the same... }
  1060.       Mode :=pmNotXor;
  1061.       Style:=psSolid;
  1062.       Width:=1;
  1063.     end;
  1064.     Brush.Style:=bsClear;
  1065.     With IZoom do Rectangle(X0,Y0,X1,Y1);
  1066.   end;
  1067. end;
  1068.  
  1069. Function TCustomTeePanel.GetCursorPos:TPoint;
  1070. Begin
  1071.   {$IFDEF D1}
  1072.   WinProcs.GetCursorPos(result);
  1073.   {$ELSE}
  1074.   Windows.GetCursorPos(result);
  1075.   {$ENDIF}
  1076.   result:=ScreenToClient(result);
  1077. end;
  1078.  
  1079. Function TCustomTeePanel.GetRectangle:TRect;
  1080. begin
  1081.   result:=GetClientRect;
  1082. end;
  1083.  
  1084. Procedure TCustomTeePanel.DrawToMetaCanvas(ACanvas:TCanvas; Const Rect:TRect);
  1085. Var Old:Boolean;
  1086. begin  { assume the acanvas is in MM_ANISOTROPIC mode }
  1087.   InternalCanvas.Metafiling:=True;
  1088.   Old:=BufferedDisplay;
  1089.   BufferedDisplay:=False;
  1090.   try
  1091.     Draw(ACanvas,Rect);
  1092.   finally
  1093.     BufferedDisplay:=Old;
  1094.     InternalCanvas.Metafiling:=False;
  1095.   end;
  1096. end;
  1097.  
  1098. Function TCustomTeePanel.GetMonochrome:Boolean;
  1099. Begin
  1100.   result:=InternalCanvas.Monochrome;
  1101. end;
  1102.  
  1103. Procedure TCustomTeePanel.SetMonochrome(Value:Boolean);
  1104. Begin
  1105.   InternalCanvas.Monochrome:=Value;
  1106. end;
  1107.  
  1108. Procedure TCustomTeePanel.Assign(Source:TPersistent);
  1109. begin
  1110.   if Source is TCustomTeePanel then
  1111.   With TCustomTeePanel(Source) do
  1112.   begin
  1113.     Self.BufferedDisplay    := BufferedDisplay;
  1114.     Self.FPrintProportional := FPrintProportional;
  1115.     Self.FPrintResolution   := FPrintResolution;
  1116.     Self.FMargins           := FMargins;
  1117.     Self.Monochrome         := Monochrome;
  1118.     Self.FView3D            := FView3D;
  1119.     Self.FView3DOptions.Assign(FView3DOptions);
  1120.     Self.F3DPercent         := F3DPercent;
  1121.     Self.Color              := Color;
  1122.   end
  1123.   else inherited Assign(Source);
  1124. end;
  1125.  
  1126. Procedure TCustomTeePanel.SaveToMetafile(Const FileName:String);
  1127. begin
  1128.   SaveToMetaFileRect(False,FileName,GetRectangle);
  1129. end;
  1130.  
  1131. Procedure TCustomTeePanel.SaveToMetafileEnh(Const FileName:String);
  1132. begin
  1133.   SaveToMetaFileRect(True,FileName,GetRectangle);
  1134. end;
  1135.  
  1136. { Enhanced:Boolean }
  1137. Procedure TCustomTeePanel.SaveToMetafileRect( Enhanced:Boolean;
  1138.                                            Const FileName:String;
  1139.                                            Const Rect:TRect);
  1140. Var tmpStream:TFileStream;
  1141.     Meta:TMetafile;
  1142. Begin
  1143.   Meta:=TeeCreateMetafile(Enhanced,Rect);
  1144.   With Meta do
  1145.   try
  1146.     tmpStream:=TFileStream.Create(FileName,fmCreate);
  1147.     try
  1148.       SaveToStream(tmpStream);
  1149.     finally
  1150.       tmpStream.Free;
  1151.     end;
  1152.   finally
  1153.     Free;
  1154.   end;
  1155. End;
  1156.  
  1157. Function TCustomTeePanel.TeeCreateBitmap(ABackColor:TColor; Const Rect:TRect):TBitmap;
  1158. var Old  : Boolean;
  1159. begin
  1160.   result:=TBitmap.Create;
  1161.   With result do
  1162.   begin
  1163.     Width := Rect.Right-Rect.Left;
  1164.     Height:= Rect.Bottom-Rect.Top;
  1165.     if ABackColor<>clWhite then
  1166.     begin
  1167.       Canvas.Brush.Color:=ABackColor;
  1168.       Canvas.FillRect(Rect);
  1169.     end;
  1170.     Old:=BufferedDisplay;
  1171.     BufferedDisplay:=False;
  1172.     Self.Draw(Canvas,Rect);
  1173.     BufferedDisplay:=Old;
  1174.   end;
  1175. end;
  1176.  
  1177. Procedure TCustomTeePanel.SaveToBitmapFile(Const FileName:String);
  1178. Begin
  1179.   With TeeCreateBitmap(clWhite,GetRectangle) do
  1180.   try
  1181.     SaveToFile(FileName);
  1182.   finally
  1183.     Free;
  1184.   end;
  1185. End;
  1186.  
  1187. Procedure TCustomTeePanel.PrintPortrait;
  1188. Begin
  1189.   PrintOrientation(poPortrait);
  1190. end;
  1191.  
  1192. Procedure TCustomTeePanel.PrintLandscape;
  1193. Begin
  1194.   PrintOrientation(poLandscape);
  1195. end;
  1196.  
  1197. Procedure TCustomTeePanel.PrintOrientation(AOrientation:TPrinterOrientation);
  1198. Var OldOrientation:TPrinterOrientation;
  1199. Begin
  1200.   OldOrientation:=Printer.Orientation;
  1201.   Printer.Orientation:=AOrientation;
  1202.   try
  1203.     Print;
  1204.   finally
  1205.     Printer.Orientation:=OldOrientation;
  1206.   end;
  1207. end;
  1208.  
  1209. Procedure TCustomTeePanel.CopyToClipboardBitmap;
  1210. var tmpBitmap:TBitmap;
  1211. begin
  1212.   tmpBitmap:=TeeCreateBitmap(clWhite,GetRectangle);
  1213.   with tmpBitmap do
  1214.   try
  1215.     ClipBoard.Assign(tmpBitmap);
  1216.   finally
  1217.     tmpBitmap.Free;
  1218.   end;
  1219. end;
  1220.  
  1221. Procedure TCustomTeePanel.CopyToClipboardMetafile(Enhanced:Boolean);
  1222. Var Meta:TMetaFile;
  1223. begin
  1224.   Meta:=TeeCreateMetafile(Enhanced,GetRectangle);
  1225.   try
  1226.     ClipBoard.Assign(Meta);
  1227.   finally
  1228.     Meta.Free;
  1229.   end;
  1230. end;
  1231.  
  1232. Procedure TCustomTeePanel.CalcMetaBounds( Var R:TRect;
  1233.                                           Const AChartRect:TRect;
  1234.                                           Var WinWidth,WinHeight,
  1235.                                           ViewWidth,ViewHeight:Longint);
  1236. Var tmpRectWidth,
  1237.     tmpRectHeight:Longint;
  1238. begin  { apply PrintResolution to the desired rectangle coordinates }
  1239.   RectSize(R,ViewWidth,ViewHeight);
  1240.   RectSize(AChartRect,tmpRectWidth,tmpRectHeight);
  1241.   WinWidth :=tmpRectWidth -MulDiv(tmpRectWidth, PrintResolution,100);
  1242.   WinHeight:=tmpRectHeight-MulDiv(tmpRectHeight,PrintResolution,100);
  1243.   With R do
  1244.   begin
  1245.     Left  :=MulDiv(Left  ,WinWidth,ViewWidth);
  1246.     Right :=MulDiv(Right ,WinWidth,ViewWidth);
  1247.     Top   :=MulDiv(Top   ,WinHeight,ViewHeight);
  1248.     Bottom:=MulDiv(Bottom,WinHeight,ViewHeight);
  1249.   end;
  1250. end;
  1251.  
  1252. Procedure TCustomTeePanel.PrintPartialCanvas( PrintCanvas:TCanvas;
  1253.                                               Const PrinterRect:TRect);
  1254. Var ViewWidth   : Longint;
  1255.     ViewHeight  : Longint;
  1256.     WinWidth    : Longint;
  1257.     WinHeight   : Longint;
  1258.     tmpR        : TRect;
  1259.  
  1260.   Procedure SetAnisotropic; { change canvas/windows metafile mode }
  1261.   Var DC : HDC;
  1262.   begin
  1263.     DC:=PrintCanvas.Handle;
  1264.     SetMapMode(DC, MM_ANISOTROPIC);
  1265.     SetWindowOrgEx(  DC, 0, 0, nil);
  1266.     SetWindowExtEx(  DC, WinWidth, WinHeight, nil);
  1267.     SetViewportExtEx(DC, ViewWidth,ViewHeight, nil);
  1268.     SetViewportOrgEx(DC, 0, 0, nil);
  1269.   end;
  1270.  
  1271. Begin
  1272.   tmpR:=PrinterRect;
  1273.   { check if margins inverted }
  1274.   if tmpR.Left>tmpR.Right then SwapInteger(tmpR.Left,tmpR.Right);
  1275.   if tmpR.Top>tmpR.Bottom then SwapInteger(tmpR.Top,tmpR.Bottom);
  1276.  
  1277.   { apply PrintResolution to dimensions }
  1278.   CalcMetaBounds(tmpR,GetRectangle,WinWidth,WinHeight,ViewWidth,ViewHeight);
  1279.  
  1280.   SetAnisotropic;
  1281.   FPrinting:=True;
  1282.   try
  1283.     if CanClip then ClipCanvas(PrintCanvas,tmpR);
  1284.     DrawToMetaCanvas(PrintCanvas,tmpR);
  1285.     UnClipCanvas(PrintCanvas);
  1286.   finally
  1287.     FPrinting:=False;
  1288.   end;
  1289. end;
  1290.  
  1291. Procedure TCustomTeePanel.PrintPartial(Const PrinterRect:TRect);
  1292. Begin
  1293.   PrintPartialCanvas(Printer.Canvas,PrinterRect);
  1294. End;
  1295.  
  1296. Procedure TCustomTeePanel.PrintRect(Const R:TRect);
  1297. Begin
  1298.   Printer.Title:=Name;
  1299.   Printer.BeginDoc;
  1300.   try
  1301.     PrintPartial(R);
  1302.     Printer.EndDoc;
  1303.   except
  1304.     on Exception do
  1305.     begin
  1306.       Printer.Abort;
  1307.       if Printer.Printing then Printer.EndDoc;
  1308.       Raise;
  1309.     end;
  1310.   end;
  1311. end;
  1312.  
  1313. Function TCustomTeePanel.CalcProportionalMargins:TRect;
  1314.  
  1315.   Function CalcMargin(Size1,Size2:Integer; Const ARatio:Double):Integer;
  1316.   Var tmpPrinterRatio:Double;
  1317.   begin
  1318.     tmpPrinterRatio:= GetDeviceCaps(Printer.Handle,LOGPIXELSX)/
  1319.                       GetDeviceCaps(Printer.Handle,LOGPIXELSY);
  1320.     result:=Round(100.0*(Size2-((Size1-(40.0*Size1*0.01))*ARatio*tmpPrinterRatio))/Size2) div 2;
  1321.   end;
  1322.  
  1323. Var tmp      : Integer;
  1324.     tmpWidth : Integer;
  1325.     tmpHeight: Integer;
  1326. begin
  1327.   With GetRectangle do
  1328.   begin
  1329.     tmpWidth:=Right-Left;
  1330.     tmpHeight:=Bottom-Top;
  1331.   end;
  1332.   if tmpWidth > tmpHeight then
  1333.   begin
  1334.     tmp:=CalcMargin(Printer.PageWidth,Printer.PageHeight,tmpHeight/tmpWidth);
  1335.     Result:=Rect(TeeDefault_PrintMargin,tmp,TeeDefault_PrintMargin,tmp);
  1336.   end
  1337.   else
  1338.   begin
  1339.     tmp:=CalcMargin(Printer.PageHeight,Printer.PageWidth,tmpWidth/tmpHeight);
  1340.     Result:=Rect(tmp,TeeDefault_PrintMargin,tmp,TeeDefault_PrintMargin);
  1341.   end;
  1342. end;
  1343.  
  1344. Function TCustomTeePanel.ChartPrintRect:TRect;
  1345. Var tmpLog:Array[Boolean] of Longint;
  1346.  
  1347.   Function InchToPixel(Horizontal:Boolean; Const Inch:Double):Integer;
  1348.   begin
  1349.     result:=Round(Inch*tmpLog[Horizontal]);
  1350.   end;
  1351.  
  1352. Var tmp:Double;
  1353. Begin
  1354.   if FPrintProportional then PrintMargins:=CalcProportionalMargins;
  1355.   { calculate margins in pixels and calculate the remaining rectangle in pixels }
  1356.   tmpLog[True]:=GetDeviceCaps(Printer.Handle,LOGPIXELSX);
  1357.   tmpLog[False]:=GetDeviceCaps(Printer.Handle,LOGPIXELSY);
  1358.   With result do
  1359.   Begin
  1360.     tmp   :=0.01*Printer.PageWidth/(1.0*tmpLog[True]);
  1361.     Left  :=InchToPixel(True,1.0*PrintMargins.Left*tmp);
  1362.     Right :=Printer.PageWidth-InchToPixel(True,1.0*PrintMargins.Right*tmp);
  1363.  
  1364.     tmp   :=0.01*Printer.PageHeight/(1.0*tmpLog[False]);
  1365.     Top   :=InchToPixel(False,1.0*PrintMargins.Top*tmp);
  1366.     Bottom:=Printer.PageHeight-InchToPixel(False,1.0*PrintMargins.Bottom*tmp);
  1367.   end;
  1368. end;
  1369.  
  1370. Procedure TCustomTeePanel.Print;
  1371. Begin
  1372.   PrintRect(ChartPrintRect);
  1373. end;
  1374.  
  1375. Procedure TCustomTeePanel.CheckPenWidth(APen:TPen);
  1376. begin
  1377.   if Printing and (APen.Style<>psSolid) and (APen.Width=1) then
  1378.      APen.Width:=0;  { <-- fixes some printer's bug (HP Laserjets?) }
  1379. end;
  1380.  
  1381. Procedure TCustomTeePanel.DrawPanelBevels(Rect:TRect);
  1382. Const Colors:Array[Boolean] of TColor=(clBtnHighlight,clBtnShadow);
  1383. begin
  1384.   if BevelOuter <> bvNone then
  1385.      Frame3D(Canvas.ReferenceCanvas,Rect,Colors[BevelOuter=bvLowered],Colors[BevelOuter=bvRaised],BevelWidth);
  1386.   Frame3D(Canvas.ReferenceCanvas, Rect, Color, Color, BorderWidth);
  1387.   if BevelInner <> bvNone then
  1388.      Frame3D(Canvas.ReferenceCanvas, Rect, Colors[BevelInner=bvLowered],Colors[BevelInner=bvRaised], BevelWidth);
  1389. end;
  1390.  
  1391. { TCustomTeePanelExtended }
  1392. Procedure TCustomTeePanelExtended.SetAnimatedZoom(Value:Boolean);
  1393. Begin
  1394.   SetBooleanProperty(FAnimatedZoom,Value);
  1395. end;
  1396.  
  1397. Procedure TCustomTeePanelExtended.SetAnimatedZoomSteps(Value:Integer);
  1398. Begin
  1399.   SetIntegerProperty(FAnimatedZoomSteps,Value);
  1400. end;
  1401.  
  1402. procedure TCustomTeePanelExtended.SetBackImage(Value:TPicture);
  1403. begin
  1404.   FBackImage.Assign(Value);
  1405. end;
  1406.  
  1407. procedure TCustomTeePanelExtended.SetBackImageMode(Value:TTeeBackImageMode);
  1408. Begin
  1409.   if FBackImageMode<>Value then
  1410.   begin
  1411.     FBackImageMode:=Value;
  1412.     Invalidate;
  1413.   end;
  1414. End;
  1415.  
  1416. Constructor TCustomTeePanelExtended.Create(AOwner: TComponent);
  1417. begin
  1418.   inherited Create(AOwner);
  1419.   FGradient :=TChartGradient.Create(Self);
  1420.   FBackImageMode:=pbmStretch;
  1421.   FBackImage:=TPicture.Create;
  1422.   FBackImage.OnChange:=CanvasChanged;
  1423.   FAnimatedZoomSteps:=8;
  1424.   FAllowZoom:=True;
  1425.   FAllowPanning:=pmBoth;
  1426. end;
  1427.  
  1428. Destructor TCustomTeePanelExtended.Destroy;
  1429. Begin
  1430.   FGradient.Free;
  1431.   FBackImage.Free;
  1432.   inherited Destroy;
  1433. end;
  1434.  
  1435. procedure TCustomTeePanelExtended.UndoZoom;
  1436. begin
  1437.   if Assigned(FOnUndoZoom) then FOnUndoZoom(Self);
  1438.   Invalidate;
  1439.   FZoomed:=False;
  1440. end;
  1441.  
  1442. procedure TCustomTeePanelExtended.SetGradient(Value:TChartGradient);
  1443. begin
  1444.   FGradient.Assign(Value);
  1445. end;
  1446.  
  1447. Procedure TCustomTeePanelExtended.Assign(Source:TPersistent);
  1448. begin
  1449.   if Source is TCustomTeePanelExtended then
  1450.   With TCustomTeePanelExtended(Source) do
  1451.   begin
  1452.     Self.FBackImage.Assign(FBackImage);
  1453.     Self.FBackImageMode   := FBackImageMode;
  1454.     Self.FGradient.Assign(FGradient);
  1455.     Self.FAllowPanning    := FAllowPanning;
  1456.     Self.FAllowZoom       := FAllowZoom;
  1457.     Self.FAnimatedZoom    := FAnimatedZoom;
  1458.     Self.FAnimatedZoomSteps:=FAnimatedZoomSteps;
  1459.   end;
  1460.   inherited Assign(Source);
  1461. end;
  1462.  
  1463. function TCustomTeePanelExtended.GetPalette: HPALETTE;
  1464. begin
  1465.   Result := 0;    { default result is no palette }
  1466.   if Assigned(FBackImage) and (FBackImage.Graphic<>nil) and
  1467.      (FBackImage.Graphic is TBitmap) then    { only bitmaps have palettes }
  1468.          Result := TBitmap(FBackImage.Graphic).Palette;    { use it if available }
  1469. end;
  1470.  
  1471. procedure TCustomTeePanelExtended.DrawBitmap(Rect:TRect; Z:Integer);
  1472. var RectH      : LongInt;
  1473.     RectW      : LongInt;
  1474.  
  1475.     Procedure TileBitmap;
  1476.     Var tmpWidth   : LongInt;
  1477.     tmpHeight  : LongInt;
  1478.     tmpX       : LongInt;
  1479.     tmpY       : LongInt;
  1480.     begin
  1481.       tmpWidth :=BackImage.Width;
  1482.       tmpHeight:=BackImage.Height;
  1483.       { keep "painting" the wall with tiled small images... }
  1484.       if (tmpWidth>0) and (tmpHeight>0) then
  1485.       Begin
  1486.     tmpY:=0;
  1487.     while tmpY<RectH do
  1488.     begin
  1489.       tmpX:=0;
  1490.       while tmpX<RectW do
  1491.       begin
  1492.         Canvas.Draw(Rect.Left+tmpX,Rect.Top+tmpY,BackImage.Graphic);
  1493.         Inc(tmpX,tmpWidth);
  1494.       end;
  1495.       Inc(tmpY,tmpHeight);
  1496.     end;
  1497.       end;
  1498.     end;
  1499.  
  1500.     Procedure Calc3DRect;
  1501.     begin
  1502.       With Rect do
  1503.       begin
  1504.     TopLeft:=Canvas.Calculate3DPosition(Left,Top,Z);
  1505.     BottomRight:=Canvas.Calculate3DPosition(Right,Bottom,Z);
  1506.     if not View3D then Inc(Top);
  1507.       end;
  1508.     end;
  1509.  
  1510. Var ShouldClip:Boolean;
  1511. Begin
  1512.   if (Z=0) or ((not View3D) or (View3DOptions.Orthogonal)) then
  1513.   if FBackImage.Graphic<>nil then
  1514.   begin
  1515.     {$IFDEF D1}
  1516.     { try to improve bmp palette on D1 }
  1517.     SelectPalette(Canvas.Handle, FBackImage.Bitmap.Palette, True);
  1518.     RealizePalette(Canvas.Handle);
  1519.     {$ENDIF}
  1520.     if FBackImageMode=pbmStretch then
  1521.     begin
  1522.       if Z>0 then Calc3DRect;
  1523.       Canvas.StretchDraw(Rect,FBackImage.Graphic);
  1524.     end
  1525.     else
  1526.     begin
  1527.       ShouldClip:=CanClip;
  1528.       if ShouldClip then
  1529.      if Z=0 then Canvas.ClipRectangle(Rect)
  1530.         else Canvas.ClipCube(Rect,0,Width3D);
  1531.       if Z>0 then Calc3DRect;
  1532.       RectSize(Rect,RectW,RectH);
  1533.       if FBackImageMode=pbmTile then TileBitmap
  1534.       else { draw centered }
  1535.       Begin
  1536.     FillPanelRect(Rect);
  1537.     Canvas.Draw( Rect.Left+((RectW-BackImage.Width) div 2),
  1538.              Rect.Top +((RectH-BackImage.Height) div 2),
  1539.              BackImage.Graphic);
  1540.       end;
  1541.       if ShouldClip then Canvas.UnClipRectangle;
  1542.     end;
  1543.   end;
  1544. end;
  1545.  
  1546. Procedure TCustomTeePanelExtended.DrawImage(Const R:TRect);
  1547. begin
  1548.   if (FBackImage.Graphic<>nil) then DrawBitmap(R,0);
  1549. end;
  1550.  
  1551. procedure TCustomTeePanelExtended.PanelPaint(Const UserRect:TRect);
  1552. Var Rect : TRect;
  1553. begin
  1554.   Rect:=UserRect;
  1555.   FillPanelRect(Rect);
  1556.   DrawImage(Rect);
  1557.   if (not Printing) or PrintTeePanel then
  1558.   begin
  1559.     With Canvas.Pen do
  1560.     begin
  1561.       Style:=psSolid;
  1562.       Width:=1;
  1563.       Mode:=pmCopy;
  1564.     end;
  1565.     Canvas.Brush.Style:=bsClear;
  1566.     DrawPanelBevels(Rect);
  1567.   end;
  1568. end;
  1569.  
  1570. procedure TCustomTeePanelExtended.FillPanelRect(Const Rect:TRect);
  1571. Begin
  1572.   With FGradient do
  1573.   if Visible then
  1574.   begin
  1575.     if (Direction=gdTopBottom) or (Direction=gdLeftRight) then
  1576.        Canvas.GradientFill(Rect,StartColor,EndColor,Direction)
  1577.     else
  1578.        Canvas.GradientFill(Rect,EndColor,StartColor,Direction);
  1579.   end
  1580.   else
  1581.   { PrintTeePanel is a "trick" to paint Chart background also when printing }
  1582.   if (not Printing) or PrintTeePanel then
  1583.   With Canvas do
  1584.   begin
  1585.     Brush.Color:=Self.Color;
  1586.     Brush.Style:=bsSolid;
  1587.     EraseBackground(Rect);
  1588.   end;
  1589. end;
  1590.  
  1591. { TCustomTeeGradient }
  1592. Constructor TCustomTeeGradient.Create(AOwner:TCustomTeePanel);
  1593. Begin
  1594.   inherited Create;
  1595.   FOwner      :=AOwner;
  1596.   FDirection  :=gdTopBottom;
  1597.   FStartColor :=clWhite;
  1598.   FEndColor   :=clYellow;
  1599. End;
  1600.  
  1601. Procedure TCustomTeeGradient.SetVisible(Value:Boolean);
  1602. Begin
  1603.   if FVisible<>Value then
  1604.   begin
  1605.     FVisible:=Value;
  1606.     if Assigned(FOwner) then FOwner.Invalidate;
  1607.   end;
  1608. End;
  1609.  
  1610. Procedure TCustomTeeGradient.SetDirection(Value:TGradientDirection);
  1611. Begin
  1612.   if FDirection<>Value then
  1613.   Begin
  1614.     FDirection:=Value;
  1615.     if Assigned(FOwner) then FOwner.Invalidate;
  1616.   end;
  1617. End;
  1618.  
  1619. Procedure TCustomTeeGradient.SetStartColor(Value:TColor);
  1620. Begin
  1621.   if FStartColor<>Value then
  1622.   begin
  1623.     FStartColor:=Value;
  1624.     if Assigned(FOwner) then FOwner.Invalidate;
  1625.   end;
  1626. End;
  1627.  
  1628. Procedure TCustomTeeGradient.SetEndColor(Value:TColor);
  1629. Begin
  1630.   if FEndColor<>Value then
  1631.   begin
  1632.     FEndColor:=Value;
  1633.     if Assigned(FOwner) then FOwner.Invalidate;
  1634.   end;
  1635. End;
  1636.  
  1637. Procedure TCustomTeeGradient.Assign(Source:TPersistent);
  1638. Begin
  1639.   if Source is TCustomTeeGradient then
  1640.   With TCustomTeeGradient(Source) do
  1641.   Begin
  1642.     Self.FVisible   :=FVisible;
  1643.     Self.FDirection :=FDirection;
  1644.     Self.FStartColor:=FStartColor;
  1645.     Self.FEndColor  :=FEndColor;
  1646.   end
  1647.   else inherited Assign(Source);
  1648. end;
  1649.  
  1650. { TChartFontObject }
  1651. Constructor TChartFontObject.Create(AOwner: TCustomTeePanel);
  1652. Begin
  1653.   inherited Create;
  1654.   FParentChart:=AOwner;
  1655.   FFont:=CreateDefaultFont(FParentChart.CanvasChanged);
  1656. end;
  1657.  
  1658. Function TChartFontObject.IsFontStored:Boolean;
  1659. begin
  1660.   result:=not IsDefaultFont(FFont);
  1661. end;
  1662.  
  1663. Destructor TChartFontObject.Destroy;
  1664. begin
  1665.   FFont.Free;
  1666.   inherited Destroy;
  1667. end;
  1668.  
  1669. Procedure TChartFontObject.Assign(Source:TPersistent);
  1670. Begin
  1671.   if Source is TChartFontObject then
  1672.      Self.FFont.Assign(TChartFontObject(Source).FFont)
  1673.   else
  1674.      inherited Assign(Source);
  1675. end;
  1676.  
  1677. Procedure TChartFontObject.SetFont(Value:TFont);
  1678. begin
  1679.   FFont.Assign(Value);
  1680. end;
  1681.  
  1682. Procedure TChartFontObject.Repaint;
  1683. begin
  1684.   ParentChart.Invalidate;
  1685. end;
  1686.  
  1687. { TDraw3D }
  1688. Procedure TDraw3D.InternalDraw(Const UserRectangle:TRect);
  1689. begin
  1690.   PanelPaint(UserRectangle);
  1691.   RecalcWidthHeight;
  1692.   InternalCanvas.Projection(FWidth3D,FChartBounds,ChartRect);
  1693.   Canvas.ResetState;
  1694.   if Assigned(FOnPaint) then FOnPaint(Self,UserRectangle);
  1695.  
  1696.   if IZoom.Active then DrawZoomRectangle;
  1697.   Canvas.ResetState;
  1698.   if Assigned(FOnAfterDraw) then FOnAfterDraw(Self);
  1699. end;
  1700.  
  1701. { Zoom & Scroll (Panning) }
  1702. Procedure TZoomPanningRecord.Check;
  1703. begin
  1704.   if X0>X1 Then SwapLongint(X0,X1);
  1705.   if Y0>Y1 Then SwapLongint(Y0,Y1);
  1706. end;
  1707.  
  1708. Procedure TZoomPanningRecord.Activate(x,y:Longint);
  1709. Begin
  1710.   X0:=x;  Y0:=y;
  1711.   X1:=x;  Y1:=y;
  1712.   Active:=True;
  1713. End;
  1714.  
  1715. Function TeeGetImageExtension(Index:Longint):String;
  1716. Const Extensions:Array[0..{$IFDEF TEEJPEG}4{$ELSE}3{$ENDIF}] of String=
  1717.       ('BMP','WMF','EMF','TEE'{$IFDEF TEEJPEG},'JPG'{$ENDIF});
  1718. begin
  1719.   result:=Extensions[Index];
  1720. end;
  1721.  
  1722. Function TeeIdentToCursor(Const AName:String; Var ACursor:Longint):Boolean;
  1723. begin
  1724.   if AName=TeeMsg_TeeHand then
  1725.   begin
  1726.     ACursor:=crTeeHand;
  1727.     result:=True;
  1728.   end
  1729.   else result:=IdentToCursor(AName,ACursor);
  1730. end;
  1731.  
  1732. Function TeeCursorToIdent(ACursor:Longint; Var AName:String):Boolean;
  1733. begin
  1734.   if ACursor=crTeeHand then
  1735.   begin
  1736.     AName:=TeeMsg_TeeHand;
  1737.     result:=True;
  1738.   end
  1739.   else result:=CursorToIdent(ACursor,AName);
  1740. end;
  1741.  
  1742. { Returns True if point T is over (more or less "Tolerance" pixels)
  1743.   line:  P --> Q }
  1744. Function PointInLineTolerance(Const P:TPoint; px,py,qx,qy,TolerancePixels:Integer):Boolean;
  1745.  
  1746.   Function Dif(a,b:Integer):Boolean;
  1747.   begin
  1748.     result:=(a+TolerancePixels)<b;
  1749.   end;
  1750.  
  1751. begin
  1752.   if ( Abs((qy-py)*(P.x-px)-(P.y-py)*(qx-px)) >= (MaxLong(Abs(qx-px),Abs(qy-py)))) then
  1753.       result:=False
  1754.   else
  1755.   if ((Dif(qx,px) and Dif(px,P.x)) or (Dif(qy,py) and Dif(py,P.y))) then result:=False else
  1756.   if ((Dif(P.x,px) and Dif(px,qx)) or (Dif(P.y,py) and Dif(py,qy))) then result:=False else
  1757.   if ((Dif(px,qx) and Dif(qx,P.x)) or (Dif(py,qy) and Dif(qy,P.y))) then result:=False else
  1758.   if ((Dif(P.x,qx) and Dif(qx,px)) or (Dif(P.y,qy) and Dif(qy,py))) then result:=False else
  1759.      result:=True;
  1760. end;
  1761.  
  1762. Function PointInLine(Const P:TPoint; px,py,qx,qy:Integer):Boolean;
  1763. Begin
  1764.   result:=PointInLineTolerance(P,px,py,qx,qy,0);
  1765. end;
  1766.  
  1767. Function PointInPolygon(Const P:TPoint; Const Poly:Array of TPoint):Boolean;
  1768. { slow...
  1769. Var Region:HRGN;
  1770. begin
  1771.   Region:=CreatePolygonRgn(Poly,1+High(Poly),0);
  1772.   result:=(Region>0) and PtInRegion(Region,p.x,p.y);
  1773.   DeleteObject(Region);
  1774. end;
  1775. }
  1776. Var i,j:Longint;
  1777. begin
  1778.   result:=False;
  1779.   j:=High(Poly);
  1780.   for i:=0 to High(Poly) do
  1781.   begin
  1782.     if (((( Poly[i].Y <= P.Y ) and ( P.Y < Poly[j].Y ) ) or
  1783.          (( Poly[j].Y <= P.Y ) and ( P.Y < Poly[i].Y ) )) and
  1784.           ( P.X < ( Poly[j].X - Poly[i].X ) * ( P.Y - Poly[i].Y )
  1785.           / ( Poly[j].Y - Poly[i].Y ) + Poly[i].X )) then
  1786.              result:=not result;
  1787.     j:=i;
  1788.   end;
  1789. end;
  1790.  
  1791. Function PointInTriangle(Const P:TPoint; X0,X1,Y0,Y1:Integer):Boolean;
  1792. begin
  1793.   result:=PointInPolygon(P,[ Point(X0,Y0),Point((X0+X1) div 2,Y1),Point(X1,Y0) ]);
  1794. end;
  1795.  
  1796. Function PointInHorizTriangle(Const P:TPoint; Y0,Y1,X0,X1:Integer):Boolean;
  1797. begin
  1798.   result:=PointInPolygon(P,[ Point(X0,Y0),Point(X1,(Y0+Y1) div 2),Point(X0,Y1) ]);
  1799. end;
  1800.  
  1801. Function PointInEllipse(Const P:TPoint; Const Rect:TRect):Boolean;
  1802. var tmpWidth,tmpHeight,
  1803.     tmpXCenter,tmpYCenter:Integer;
  1804. begin
  1805.   With Rect do
  1806.   begin
  1807.     tmpXCenter:= (Left+Right) div 2;
  1808.     tmpYCenter:= (Top+Bottom) div 2;
  1809.     tmpWidth  := Sqr(tmpXCenter-Left);
  1810.     tmpHeight := Sqr(tmpYCenter-Top);
  1811.   end;
  1812.   result:=(tmpWidth<>0) and (tmpHeight<>0) and
  1813.           ( (Sqr(1.0*P.X-tmpXCenter) / tmpWidth ) +
  1814.             (Sqr(1.0*P.Y-tmpYCenter) / tmpHeight) <= 1 );
  1815. end;
  1816.  
  1817. {$IFNDEF D3}
  1818. Function AnsiPos(Const SubStr,St:String):Integer;
  1819. begin
  1820.   result:=Pos(SubStr,St);
  1821. end;
  1822. {$ENDIF}
  1823.  
  1824. { Replaces all ocurrences of "Separator" in string "St" with
  1825.   #13 (TeeLineSeparator constant)  }
  1826. Procedure TeeSplitInLines(Var St:String; Const Separator:String);
  1827. var i:Integer;
  1828. begin
  1829.   Repeat
  1830.     i:=AnsiPos(Separator,St);
  1831.     if i>0 then St[i]:=TeeLineSeparator;
  1832.   Until i=0;
  1833. end;
  1834.  
  1835. { Returns 1 + how many times "TeeLineSeparator #13" is found
  1836.   inside string St parameter }
  1837. Function TeeNumTextLines(St:String):Integer;
  1838. var i : Integer;
  1839. begin
  1840.   result:=0;
  1841.   i:=AnsiPos(TeeLineSeparator,St);
  1842.   while i>0 do
  1843.   begin
  1844.     inc(result);
  1845.     Delete(St,1,i);
  1846.     i:=AnsiPos(TeeLineSeparator,St);
  1847.   end;
  1848.   if St<>'' then Inc(result);
  1849. end;
  1850.  
  1851. Function DelphiToLocalFormat(Const Format:String):String;
  1852. var t:Longint;
  1853. begin
  1854.   result:=Format;
  1855.   for t:=1 to Length(result) do
  1856.       if result[t]=',' then result[t]:=ThousandSeparator else
  1857.       if result[t]='.' then result[t]:=DecimalSeparator;
  1858. end;
  1859.  
  1860. Function LocalToDelphiFormat(Const Format:String):String;
  1861. var t:Longint;
  1862. begin
  1863.   result:=Format;
  1864.   for t:=1 to Length(result) do
  1865.       if result[t]=ThousandSeparator then result[t]:=',' else
  1866.       if result[t]=DecimalSeparator then result[t]:='.';
  1867. end;
  1868.  
  1869. Procedure EnableControls(Enable:Boolean; Const ControlArray:Array of TControl);
  1870. var t:Integer;
  1871. begin
  1872.   for t:=Low(ControlArray) to High(ControlArray) do
  1873.       ControlArray[t].Enabled:=Enable;
  1874. end;
  1875.  
  1876. Function TeeRoundDate(Const ADate:TDateTime; AStep:TDateTimeStep):TDateTime;
  1877. var Year  : Word;
  1878.     Month : Word;
  1879.     Day   : Word;
  1880. begin
  1881.   if ADate<=EncodeDate(1900,1,1) then result:=ADate
  1882.   else
  1883.   begin
  1884.     DecodeDate(ADate,Year,Month,Day);
  1885.     Case AStep of
  1886.        dtHalfMonth   : if Day>=15 then Day:=15
  1887.                                   else Day:=1;
  1888.        dtOneMonth,
  1889.        dtTwoMonths,
  1890.        dtThreeMonths,
  1891.        dtFourMonths,
  1892.        dtSixMonths   : Day:=1;
  1893.        dtOneYear     : begin
  1894.                          Day:=1;
  1895.                          Month:=1;
  1896.                        end;
  1897.     end;
  1898.     result:=EncodeDate(Year,Month,Day);
  1899.   end;
  1900. end;
  1901.  
  1902. Procedure TeeDateTimeIncrement( IsDateTime:Boolean;
  1903.                                 Increment:Boolean;
  1904.                                 Var Value:Double;
  1905.                                 Const AnIncrement:Double;
  1906.                                 tmpWhichDateTime:TDateTimeStep);
  1907. var Year  : Word;
  1908.     Month : Word;
  1909.     Day   : Word;
  1910.  
  1911.  Procedure DecMonths(HowMany:Word);
  1912.  begin
  1913.    Day:=1;
  1914.    if Month>HowMany then Dec(Month,HowMany)
  1915.    else
  1916.    begin
  1917.      Dec(Year);
  1918.      Month:=12-(HowMany-Month);
  1919.    end;
  1920.  end;
  1921.  
  1922.  Procedure IncMonths(HowMany:Word);
  1923.  begin
  1924.    Day:=1;
  1925.    Inc(Month,HowMany);
  1926.    if Month>12 then
  1927.    begin
  1928.      Inc(Year);
  1929.      Month:=Month-12;
  1930.    end;
  1931.  end;
  1932.  
  1933.  Procedure IncDecMonths(HowMany:Word);
  1934.  begin
  1935.    if Increment then IncMonths(HowMany)
  1936.                 else DecMonths(HowMany);
  1937.  end;
  1938.  
  1939. begin
  1940.   if IsDateTime then
  1941.   begin
  1942.     DecodeDate(Value,year,month,day);
  1943.     Case tmpWhichDateTime of
  1944.        dtHalfMonth   : Begin
  1945.                          if Day>15 then Day:=15
  1946.                          else
  1947.                          if Day>1 then Day:=1
  1948.                          else
  1949.                          begin
  1950.                            IncDecMonths(1);
  1951.                            Day:=15;
  1952.                          end;
  1953.                        end;
  1954.        dtOneMonth    : IncDecMonths(1);
  1955.        dtTwoMonths   : IncDecMonths(2);
  1956.        dtThreeMonths : IncDecMonths(3);
  1957.        dtFourMonths  : IncDecMonths(4);
  1958.        dtSixMonths   : IncDecMonths(6);
  1959.        dtOneYear     : if Increment then Inc(year) else Dec(year);
  1960.     else
  1961.     begin
  1962.       if Increment then Value:=Value+AnIncrement
  1963.                    else Value:=Value-AnIncrement;
  1964.       Exit;
  1965.     end;
  1966.     end;
  1967.     Value:=EncodeDate(year,month,day);
  1968.   end
  1969.   else
  1970.   begin
  1971.     if Increment then Value:=Value+AnIncrement
  1972.                  else Value:=Value-AnIncrement;
  1973.   end;
  1974. end;
  1975.  
  1976. Function TeeNextStep(Const OldStep:Double):Double;
  1977. Begin
  1978.   if OldStep >= 10 then result := 10*TeeNextStep(0.1*OldStep)
  1979.   else
  1980.   if OldStep < 1 then result := 0.1*TeeNextStep(OldStep*10)
  1981.   else
  1982.   if OldStep < 2 then result:=2 else
  1983.   if OldStep < 5 then result:=5 else result:=10
  1984. end;
  1985.  
  1986. {$IFDEF D3}
  1987. type PClassBitmap=^TClassBitmap;
  1988.      TClassBitmap=Record
  1989.        AClass  : TObject;
  1990.        ABitmap : TBitmap;
  1991.      end;
  1992.  
  1993. function LoadClassBitmap(HInstance: Longint; Data: Pointer): Boolean;
  1994.  
  1995.   Function TryFindResource(Const ResName:String):Boolean;
  1996.   var tmpSt:Array[0..255] of Char;
  1997.   begin
  1998.     StrPCopy(tmpSt,ResName);
  1999.     if FindResource(HInstance, tmpSt, RT_BITMAP)<>0 then
  2000.     begin
  2001.       PClassBitmap(Data)^.ABitmap.LoadFromResourceName(HInstance,tmpSt);
  2002.       result:=True;
  2003.     end
  2004.     else result:=False;
  2005.   end;
  2006.  
  2007. begin
  2008.   result:=True;
  2009.   try
  2010.     With PClassBitmap(Data)^ do
  2011.     if TryFindResource(AClass.ClassName) or
  2012.        TryFindResource(AClass.ClassParent.ClassName) then
  2013.          result:=False;
  2014.   except
  2015.     on Exception do ;
  2016.   end;
  2017. end;
  2018. {$ENDIF}
  2019.  
  2020. Procedure TeeGetClassNameBitmap(AClass:TComponent; ABitmap:TBitmap);
  2021. {$IFDEF D3}
  2022. Var tmpBitmap:TClassBitmap;
  2023. {$ELSE}
  2024. {$IFDEF D2C1}
  2025. Var tmpSt:Array[0..255] of Char;
  2026. {$ELSE}
  2027. {$IFDEF D1}
  2028. Var tmpSt:Array[0..255] of Char;
  2029. {$ENDIF}
  2030. {$ENDIF}
  2031. {$ENDIF}
  2032. begin
  2033.   {$IFDEF D3}
  2034.   tmpBitmap.ABitmap:=ABitmap;
  2035.   tmpBitmap.AClass:=AClass;
  2036.   EnumModules(LoadClassBitmap,@tmpBitmap);
  2037.   {$ELSE}
  2038.   try
  2039.     {$IFDEF D1}
  2040.     ABitmap.Handle:=LoadBitmap(Hinstance,StrPCopy(tmpSt,AClass.ClassName));
  2041.     {$ELSE}
  2042.     if FindResource(HInstance, {$IFDEF D2C1}StrPCopy(tmpSt,AClass.ClassName)
  2043.                                {$ELSE}PChar(AClass.ClassName)
  2044.                                {$ENDIF}, RT_BITMAP)<>0 then
  2045.        ABitmap.LoadFromResourceName(HInstance,AClass.ClassName)
  2046.     else
  2047.     if FindResource(HInstance, {$IFDEF D2C1}StrPCopy(tmpSt,AClass.ClassParent.ClassName)
  2048.                                {$ELSE}PChar(AClass.ClassParent.ClassName)
  2049.                                {$ENDIF}, RT_BITMAP)<>0 then
  2050.        ABitmap.LoadFromResourceName(HInstance,AClass.ClassParent.ClassName)
  2051.     {$ENDIF}
  2052.   except
  2053.     on Exception do ;
  2054.   end;
  2055.   {$ENDIF}
  2056. end;
  2057.  
  2058. Const TeeFieldsSeparator=';';
  2059.  
  2060. Function TeeNumFields(St:String):Integer;
  2061. var i:Integer;
  2062. begin
  2063.   if St<>'' then
  2064.   begin
  2065.     result:=1;
  2066.     i:=AnsiPos(TeeFieldsSeparator,St);
  2067.     While i>0 do
  2068.     begin
  2069.       Inc(result);
  2070.       Delete(St,1,i);
  2071.       i:=AnsiPos(TeeFieldsSeparator,St);
  2072.     end;
  2073.   end
  2074.   else result:=0;
  2075. end;
  2076.  
  2077. Function TeeExtractField(St:String; Index:Integer):String;
  2078. var i:Integer;
  2079. begin
  2080.   if St<>'' then
  2081.   begin
  2082.     i:=AnsiPos(TeeFieldsSeparator,St);
  2083.     While i>0 do
  2084.     begin
  2085.       Dec(Index);
  2086.       if Index=0 then
  2087.       begin
  2088.         result:=Copy(St,1,i-1);
  2089.         exit;
  2090.       end;
  2091.       Delete(St,1,i);
  2092.       i:=AnsiPos(TeeFieldsSeparator,St);
  2093.     end;
  2094.     result:=St;
  2095.   end;
  2096. end;
  2097.  
  2098. { Helper functions for runtime Series creation }
  2099. Function TeeGetUniqueName(AOwner:TComponent; Const AStartName:String):String;
  2100. Var tmp   : Longint;
  2101.     tmpSt : String;
  2102.     {$IFNDEF TEEOCX}
  2103.     tmpForm:{$IFDEF D3}TCustomForm{$ELSE}TForm{$ENDIF};
  2104.     {$ENDIF}
  2105. begin
  2106.   result:='';
  2107.   {$IFNDEF D1}
  2108.   if AOwner is {$IFDEF D3}TCustomForm{$ELSE}TForm{$ENDIF} then
  2109.   begin
  2110.     {$IFNDEF TEEOCX}
  2111.     tmpForm:={$IFDEF D3}TCustomForm{$ELSE}TForm{$ENDIF}(AOwner);
  2112.     if tmpForm.Designer<>nil then
  2113.        {$IFDEF D4}
  2114.        result := (tmpForm.Designer as IFormDesigner).UniqueName(AStartName);
  2115.        {$ELSE}
  2116.        result := TFormDesigner(tmpForm.Designer).UniqueName(AStartName);
  2117.        {$ENDIF}
  2118.     {$ENDIF}
  2119.   end;
  2120.   {$ENDIF}
  2121.   if result='' then
  2122.   begin
  2123.     {$IFDEF TEEOCX}
  2124.     tmp:=0;
  2125.     {$ELSE}
  2126.     tmp:=1;
  2127.     {$ENDIF}
  2128.     tmpSt:=AStartName+IntToStr(tmp);
  2129.     while (AOwner.FindComponent(tmpSt)<>nil) do
  2130.     begin
  2131.       Inc(tmp);
  2132.       tmpSt:=AStartName+IntToStr(tmp);
  2133.     end;
  2134.     result:=tmpSt;
  2135.   end;
  2136. end;
  2137.  
  2138. initialization
  2139.   TeeClipWhenPrinting   := {$IFDEF D1}False{$ELSE}True{$ENDIF};
  2140.   TeeClipWhenMetafiling := {$IFDEF D1}False{$ELSE}True{$ENDIF};
  2141.   TeeEraseBack          := {$IFDEF D1}True{$ELSE}False{$ENDIF};  { erase background before repainting panel }
  2142.   PrintTeePanel         := False; { Should Panel background to be printed ? Default: False }
  2143.   Screen.Cursors[crTeeHand]:=LoadCursor(HInstance,'TEE_CURSOR_HAND');
  2144. {$IFNDEF D1}
  2145. finalization
  2146.   Screen.Cursors[crTeeHand]:=0;
  2147. {$ENDIF}
  2148. end.
  2149.